package cmd

import (
	"fmt"
	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/transform"
	"io"
	"os/exec"
	"runtime"
	"strings"
	"unicode/utf8"
)

// SystemInfo 包含系统信息
type SystemInfo struct {
	OS      string
	Version string
	Kernel  string
}

// GetKernelInfo 获取内核信息
func GetKernelInfo() (string, error) {
	cmd := exec.Command("uname", "-r")
	output, err := ExecuteSystemCommand(cmd)
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(output), nil
}

// GetDarwinSystemInfo 获取 macOS 系统信息
func GetDarwinSystemInfo() (*SystemInfo, error) {
	cmd := exec.Command("sw_vers")
	output, err := ExecuteSystemCommand(cmd)
	if err != nil {
		return nil, fmt.Errorf("获取 macOS 系统信息失败: %w", err)
	}

	return ParseDarwinSystemInfo(output)
}

// GetGenericSystemInfo 获取通用系统信息
func GetGenericSystemInfo() (*SystemInfo, error) {
	cmd := exec.Command("uname", "-a")
	output, err := ExecuteSystemCommand(cmd)
	if err != nil {
		return nil, fmt.Errorf("获取系统信息失败: %w", err)
	}

	return &SystemInfo{
		OS:      runtime.GOOS,
		Version: strings.TrimSpace(output),
		Kernel:  strings.TrimSpace(output),
	}, nil
}

// GetLinuxDistribution 获取 Linux 发行版信息
func GetLinuxDistribution() (string, error) {
	// 尝试读取 /etc/os-release
	cmd := exec.Command("cat", "/etc/os-release")
	output, err := ExecuteSystemCommand(cmd)
	if err == nil {
		return ParseOSRelease(output), nil
	}

	// 尝试读取 /etc/lsb-release
	cmd = exec.Command("cat", "/etc/lsb-release")
	output, err = ExecuteSystemCommand(cmd)
	if err == nil {
		return ParseLSBRelease(output), nil
	}

	// 使用 uname
	cmd = exec.Command("uname", "-o")
	output, err = ExecuteSystemCommand(cmd)
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(output), nil
}

// GetLinuxSystemInfo 获取 Linux 系统信息
func GetLinuxSystemInfo() (*SystemInfo, error) {
	// 获取发行版信息
	osName, err := GetLinuxDistribution()
	if err != nil {
		osName = "Linux"
	}

	// 获取内核信息
	kernel, err := GetKernelInfo()
	if err != nil {
		kernel = "未知"
	}

	return &SystemInfo{
		OS:      osName,
		Version: kernel,
		Kernel:  kernel,
	}, nil
}

// GetSystemInfo2 获取系统信息（向后兼容）
func GetSystemInfo2() (string, error) {
	info, err := GetSystemInfo()
	if err != nil {
		return "", err
	}

	if info.Version != "" {
		return fmt.Sprintf("%s %s", info.OS, info.Version), nil
	}
	return info.OS, nil
}

// GetSystemInfo 获取系统信息
func GetSystemInfo() (*SystemInfo, error) {
	switch runtime.GOOS {
	case "windows":
		return GetWindowsSystemInfo()
	case "linux":
		return GetLinuxSystemInfo()
	case "darwin":
		return GetDarwinSystemInfo()
	default:
		return GetGenericSystemInfo()
	}
}

// CleanupWindowsOutput 清理 Windows 输出中的乱码字符
func CleanupWindowsOutput(output string) string {
	// 移除不可打印字符和乱码
	var result strings.Builder
	for _, r := range output {
		if r == '\r' || r == '\n' || r == '\t' || r == ' ' || (r >= 32 && r < 127) || utf8.ValidRune(r) {
			result.WriteRune(r)
		} else {
			result.WriteRune('?') // 用 ? 替换乱码字符
		}
	}
	return result.String()
}

// GetWindowsInfoBySystemInfo 使用 systeminfo 获取系统信息（备用方案）
func GetWindowsInfoBySystemInfo() (*SystemInfo, error) {
	// 尝试使用英文环境
	cmd := exec.Command("cmd", "/c", "chcp 65001 && systeminfo /fo list")
	output, err := ExecuteSystemCommand(cmd)
	if err != nil {
		// 如果失败，使用默认环境
		cmd = exec.Command("systeminfo", "/fo", "list")
		rawOutput, err := ExecuteSystemCommandRaw(cmd)
		if err != nil {
			return nil, err
		}
		output = CleanupWindowsOutput(string(rawOutput))
	}

	return ParseSystemInfoOutput(output)
}

// ConvertGBKToUTF8 将 GBK 编码转换为 UTF-8
func ConvertGBKToUTF8(input string) string {
	// 将字符串转换为字节流
	reader := transform.NewReader(strings.NewReader(input), simplifiedchinese.GBK.NewDecoder())
	output, err := io.ReadAll(reader)
	if err != nil {
		// 如果转换失败，返回原始字符串
		return input
	}
	return string(output)
}

// GetWindowsInfoByPowerShell 使用 PowerShell 获取系统信息
func GetWindowsInfoByPowerShell() (*SystemInfo, error) {
	cmd := exec.Command("powershell", "-Command",
		"Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object Caption, Version | ConvertTo-Json")

	output, err := ExecuteSystemCommand(cmd)
	if err != nil {
		return nil, err
	}

	return ParsePowerShellOutput(output)
}

// GetWindowsInfoByWMIC 使用 WMIC 获取系统信息（推荐方案）
func GetWindowsInfoByWMIC() (*SystemInfo, error) {
	// 获取操作系统名称
	osCmd := exec.Command("wmic", "os", "get", "Caption", "/value")
	osOutput, err := ExecuteSystemCommand(osCmd)
	if err != nil {
		return nil, err
	}

	// 获取操作系统版本
	versionCmd := exec.Command("wmic", "os", "get", "Version", "/value")
	versionOutput, err := ExecuteSystemCommand(versionCmd)
	if err != nil {
		return nil, err
	}

	// 对中文输出进行 GBK 到 UTF-8 的转换
	osName := ExtractWMICValue(ConvertGBKToUTF8(osOutput), "Caption")
	osVersion := ExtractWMICValue(versionOutput, "Version")

	if osName == "" {
		osName = "Windows"
	}
	if osVersion == "" {
		osVersion = "未知版本"
	}

	return &SystemInfo{
		OS:      osName,
		Version: osVersion,
		Kernel:  osVersion,
	}, nil
}

// GetWindowsSystemInfo 获取 Windows 系统信息
func GetWindowsSystemInfo() (*SystemInfo, error) {
	// 方案1: 使用 wmic 命令获取系统信息（英文输出）
	info, err := GetWindowsInfoByWMIC()
	if err == nil {
		return info, nil
	}

	// 方案2: 使用 PowerShell 获取系统信息
	info, err = GetWindowsInfoByPowerShell()
	if err == nil {
		return info, nil
	}

	// 方案3: 使用 systeminfo 并尝试处理编码问题
	return GetWindowsInfoBySystemInfo()
}
